package org.mclll.xwangplugin.town.command.executor;

import com.google.common.collect.Lists;
import de.tr7zw.nbtapi.NBT;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.milkbowl.vault.economy.Economy;
import org.black_ixx.bossshop.BossShop;
import org.black_ixx.bossshop.core.BSBuy;
import org.black_ixx.bossshop.core.BSShop;
import org.black_ixx.bossshop.core.prices.BSPriceType;
import org.black_ixx.bossshop.core.rewards.BSRewardType;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.mclll.xwangplugin.town.database.domain.TownDO;
import org.mclll.xwangplugin.town.database.domain.TownShopDO;
import org.mclll.xwangplugin.town.database.mapper.manage.TownManage;
import org.mclll.xwangplugin.town.database.mapper.manage.TownShopManage;
import org.mclll.xwangplugin.town.enums.TownLevel;
import org.mclll.xwangplugin.util.PlayerTools;

import java.util.ArrayList;
import java.util.List;

import static org.mclll.xwangplugin.town.config.TownContext.*;

public class TownShopExecutor {

    public static final String menuName = "townShop";
    private static Economy econ = null;
    private final static String LINE_1_FORMAT = "§7%s 镇的特产";
    public final static String LINE_N_FORMAT = "§e◆ 使用 §f%.2f %s §e购买 §f%d §e个";

    /**
     * 城镇商店 - shop <城镇名> <玩家名>
     */
    public static void townShop(CommandSender sender, String[] args) {
        Player player = null;
        if (args.length == 3) {
            OfflinePlayer offlineOrOnlinePlayerByName = PlayerTools.getOfflineOrOnlinePlayerByName(args[2]);
            if (!offlineOrOnlinePlayerByName.isOnline()) {
                sender.sendMessage("目标玩家不在线");
                return;
            }
            player = (Player) offlineOrOnlinePlayerByName;
        } else if (args.length != 2) {
            sender.sendMessage(TOWN_SHOP_COMMAND_FORMAT);
            return;
        }

        if (player == null) {
            if (sender instanceof Player) {
                player = (Player) sender;
            } else {
                sender.sendMessage(TOWN_SHOP_COMMAND_FORMAT);
                return;
            }
        }


        BossShop bs = (BossShop) Bukkit.getPluginManager().getPlugin("BossShopPro");
        if (bs == null) {
            return;
        }
        String townName = args[1];
        TownDO townSelectParam = new TownDO();
        townSelectParam.setName(townName);
        TownDO townDO = null;
        List<TownDO> townList = TownManage.selectList(townSelectParam);
        if (townList.isEmpty()) {
            townDO = TownManage.selectByUuid(townName);
            if (townDO == null) {
                sender.sendMessage(TOWN_NOT_FOUND);
                return;
            }
        } else {
            townDO = townList.get(0);
        }
        if (townDO.getTownLevel() == TownLevel.DUST) {
            player.sendMessage(String.format(NOW_TOWN_DUST, townDO.getName()));
            return;
        }
        BSShop shop = bs.getAPI().getShop(menuName);
        // 清理商店
        shop.getItems().clear();
        if (setupEconomy()) {
            shop.setDisplayName(
                    townDO.getName() + " 镇的商店"
            );
        }
        // 查询城镇特产，添加项目
        TownShopDO selectParam = new TownShopDO();
        selectParam.setTownUuid(townDO.getUuid());
        List<TownShopDO> townShopList = TownShopManage.selectList(selectParam);
        for (int i = 0; i < townShopList.size(); i++) {
            TownShopDO tS = townShopList.get(i);
            BSBuy bsBuy = bs.getAPI().createBSBuy(BSRewardType.Nothing, BSPriceType.Nothing,
                    null, null, null, i, null);
            ItemStack reward = NBT.itemStackFromNBT(NBT.parseNBT(tS.getRewardJson()));

            ItemStack itemStack = new ItemStack(reward.getType());
            ItemMeta itemMeta = itemStack.getItemMeta();
            itemMeta.displayName(
                    reward.getItemMeta().displayName()
            );
            ArrayList<TextComponent> lore = Lists.newArrayList(
                    Component.text(String.format(LINE_1_FORMAT, townDO.getName())),
                    Component.text("§2◆ Shift + 左键点击进入购买页面")
            );
            if (tS.getCoinGetPerPrice() > 0) {
                lore.add(Component.text(String.format(LINE_N_FORMAT, tS.getCoinGetPerPrice(), "金钱", 1)));
                lore.add(Component.text(String.format(LINE_N_FORMAT, tS.getCoinGetCount() * tS.getCoinGetPerPrice(), "金钱", tS.getCoinGetCount())));
            }
            if (tS.getPerHeartStoneGetCount() > 0) {
                lore.add(Component.text(String.format(LINE_N_FORMAT, 1.0 * tS.getPerHeartStoneGetPrice(), "心之石", tS.getPerHeartStoneGetCount())));
            }
            itemMeta.lore(lore);
            if (reward.getItemMeta().hasCustomModelData()) {
                itemMeta.setCustomModelData(reward.getItemMeta().getCustomModelData());
            }
            itemStack.setItemMeta(itemMeta);
            NBT.modify(itemStack, nbt -> {
                nbt.setString("TownShopUuid", tS.getUuid());
            });
            shop.addShopItem(bsBuy, itemStack, bs.getClassManager());
        }
        bs.getAPI().openShop(player, shop);
    }

    public static List<String> townShopTabComplete(CommandSender sender, String[] args) {
        switch (args.length) {
            case 2:
                return TownManage.selectList(null).stream()
                        .map(TownDO::getName)
                        .filter(townName -> townName.startsWith(args[1]))
                        .collect(java.util.stream.Collectors.toList());
            default:
                return null;
        }
    }

    private static boolean setupEconomy() {
        if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) {
            return false;
        }
        RegisteredServiceProvider<Economy> rsp = Bukkit.getServer().getServicesManager().getRegistration(Economy.class);
        if (rsp == null) {
            return false;
        }
        econ = rsp.getProvider();
        return econ != null;
    }
}
